package cn.base.web.support.file;

import cn.base.web.file.RemoteFileApi;
import cn.base.web.file.entity.FileUploadVO;
import cn.base.web.support.GetSessionUtils;
import cn.base.web.support.LocalMultipartFile;
import cn.rengy.isql.DbService;
import cn.rengy.isql.PageResult;
import cn.rengy.lang.ResultEntity;
import cn.rengy.tool.core.IdGenerator;
import cn.rengy.tool.core.util._DateUtils;
import cn.rengy.tool.excel.CellStyleObject;
import cn.rengy.tool.excel.HeaderCellObject;
import cn.rengy.tool.zip.ZipUtil;
import cn.rengy.util.ExceptionPrintUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Service
@Slf4j
public class ExportService {
    @Autowired(required = false)
    private DbService dbService;
    private ExecutorService executorService= Executors.newFixedThreadPool(2);
    @Autowired
    private RemoteFileApi remoteFileApi;
    /**
     * 导出查询结果
     * 导出功能为异步，导出后返回文件id
     * 前端轮询调用[/file/downloadQuery/{fileItemId}] 获得下载链接， 例：间隔1秒调用一次，持续1分钟，返回导出超时
     * @param sqlname
     * @param paramMap
     * @return
     */
    public ResultEntity exportToFile(Long pageId, String sqlname, Map<String,Object> paramMap){
        if(paramMap==null) {
            paramMap=new HashMap<String,Object>(1,1);
        }
        //查询总条数
        Long c=this.dbService.querySingleColumn(sqlname.concat("-count"),paramMap,Long.class);
        if(c.intValue()==0) {
            return ResultEntity.fail("没有需要导出的数据");
        }

        //if(columnList==null|| columnList.isEmpty()) {
        //return ResultEntity.fail("查询列信息失败");
        //}
        //Map<String, List<Map<String, Object>>> comboData=(Map<String, List<Map<String, Object>>>)grid.get("combo_data");
        Long file_item_id= IdGenerator.nextId();

        File tempDir=new File(System.getProperty("java.io.tmpdir"));//系统临时目录
        String excelName= _DateUtils.formatDate(new Date(),null,"yyyyMMddHHmmss");
        File excelFile=new File(tempDir,excelName+".xlsx");
        Long userId=GetSessionUtils.getUserId();
        Map<String, Object> finalParamMap = paramMap;
        executorService.execute(new Runnable(){
            @Override
            public void run() {
                try{
                    //1.生成excel
                    ExcelWriteUtil.writeExcel(tempDir, excelFile,new PageDataService<List<Map<String, Object>>>() {
                        @Override
                        public Map<Integer, HeaderCellObject> getHeader() {
                            Map<Integer, HeaderCellObject> headerMap=null;
                            //查询列信息
                            if(pageId!=null){
                                Map<String,Object> grid=null;//queryGridColumnV3(pageId);
                                List<Map<String, Object>> columnList=null;//(List<Map<String, Object>> )grid.get("column");
                                Map<String, List<Map<String, Object>>> comboData=null;//(Map<String, List<Map<String, Object>>>)grid.get("combo_data");
                                if(columnList!=null){
                                    CellStyleObject cellStyleObject=CellStyleObject.instance();
                                    headerMap=new LinkedHashMap<Integer, HeaderCellObject>();
                                    for(int i=0;i<columnList.size();i++){
                                        Map<String, Object> columnMap=columnList.get(i);
                                        String columnDisplayName=(String)columnMap.get("columnDisplayName");
                                        String columnName=(String)columnMap.get("columnName");
                                        HeaderCellObject headerCellObject=HeaderCellObject.instance(cellStyleObject);
                                        headerCellObject.setColumnName(columnName);
                                        headerCellObject.setText(columnDisplayName);
                                        headerMap.put(i,headerCellObject);
                                    }
                                }

                            }
                            return headerMap;
                        }

                        @Override
                        public List<Map<String, Object>> getPage(PageRequest pageRequest) {
                            String ascOrDesc=(String) finalParamMap.remove("ascOrDesc");//
                            String orderBy=(String) finalParamMap.remove("orderBy");//
                            PageResult<Map<String,Object>> pageResult=dbService.getPageNoCount(sqlname, finalParamMap,
                                    pageRequest,  ascOrDesc,  orderBy);
                            return pageResult.getRows();
                            //newSql.append(" limit ?,?");
                        }
                    });
                    //2.生成压缩文件
                    File zipFile=new File(tempDir, FilenameUtils.getBaseName(excelFile.getName()) + ".zip");
                    ZipUtil.zip(excelFile,zipFile);
                    //3.上传压缩文件
                    byte[] content= FileCopyUtils.copyToByteArray(zipFile);
                    MultipartFile multi = new LocalMultipartFile(zipFile.getName(), zipFile.getName(), "application/octet-stream", content);
                    FileUploadVO fileUploadVO=new FileUploadVO();
                    fileUploadVO.setFileId(FileConstants.tmpFileId);
                    fileUploadVO.setTargetId(userId);
                    fileUploadVO.setFileItemId(file_item_id);
                    remoteFileApi.uploadAndSave(FileConstants.tmpFileId,userId,file_item_id,multi);
                    //删除源文件
                    zipFile.delete();
                } catch (Exception e) {
                    log.error(ExceptionPrintUtils.getTrace(e));
                }
            }
        });
        return ResultEntity.ok(file_item_id);
    }
}
